package com.lixueju.security.box.web.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lixueju.security.box.core.dto.ResultData;
import com.lixueju.security.box.core.dto.SecurityBoxUtils;
import com.lixueju.security.box.core.exception.SecurityBoxException;
import com.lixueju.security.box.core.model.dto.UserToken;
import com.lixueju.security.box.core.properties.SecurityBoxConstants;
import com.lixueju.security.box.core.properties.SecurityBoxProperties;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import javax.servlet.http.HttpServletRequest;

/**
 * @author lixueju
 * @since 2019/10/9 11:39
 **/
public class SecurityBoxBaseController {

    @Autowired
    protected HttpServletRequest request;

    @Autowired
    protected SecurityBoxProperties securityBoxProperties;

    @Autowired
    protected StringRedisTemplate stringRedisTemplate;

    @Autowired
    protected JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    protected SecurityBoxUtils securityBoxUtils;

    /**
     * 自定义对象中日期格式，成功通用返回方法。
     * 日期格式默认为yyyy-MM-dd HH:mm:ss
     *
     * @param obj        需要返回的数据对象
     * @param dateFormat 日期格式（例如：yyyy-MM-dd）
     * @return
     */
    protected String callbackWithDateFormat(Object obj, String dateFormat) {
        if (!(obj instanceof ResultData)) {
            obj = new ResultData<>(obj);
        }
        if (StringUtils.isBlank(dateFormat)) {
            dateFormat = "yyyy-MM-dd HH:mm:ss";
        }
        return JSON.toJSONStringWithDateFormat(obj, dateFormat);//自动把obj为空的字段排除掉
    }

    /**
     * 成功通用返回方法
     *
     * @param obj 需要返回的数据对象
     * @return 格式化为JOSN 后的字符串
     */
    protected String callbackSuccess(Object obj) {
        return callbackWithDateFormat(obj, null);
    }

    /**
     * 失败通用返回方法
     *
     * @param message 操作失败的描述信息
     * @return 格式化为JOSN 后的字符串
     */
    protected String callbackFail(String message) {
        throw new SecurityBoxException(message);
    }

    protected Long getUserId() {
        return getUserToken().getId();
    }

    protected UserToken getUserToken() {
        return securityBoxUtils.getUserToken(request.getHeader(SecurityBoxConstants.DEFAULT_TOKEN_KEY));
    }

    /**
     * 统一获取分页对象，并设置排序
     * 如果不传递pageNo参数，默认设置为1，
     * 如果不传递pageSize参数，默认设置为10
     *
     * @param hasOrderNum T类型是否有orderNum属性
     */
    protected <T> Page<T> getPage(Boolean hasOrderNum) {
        Page<T> page = new Page<T>(getIntInRequest(request, "pageNo", 1), getIntInRequest(request, "pageSize", 10), getBooleanInRequest(request, "isSearchCount", true));
        String sortOrder = request.getParameter("sortOrder");//排序规则，ascend表示升序，descend表示降序
        String sortField = request.getParameter("sortField");//排序字段，必须和数据库字段保持一致
        String[] sortFields = StringUtils.split(sortField, ",");//支持多字段排序
        if (ObjectUtils.allNotNull(sortOrder, sortField)) {
            if ("ascend".equals(sortOrder)) {
                page.setAsc(sortFields);
            } else if ("descend".equals(sortOrder)) {
                page.setDesc(sortFields);
            }
        }
        if (hasOrderNum && !StringUtils.contains(sortField, "orderNum")) {  //有排序字段，并且没有设置该字段参与排序
            if (page.ascs() == null) {
                page.setAsc("orderNum");
            } else {
                // 拼装orderNum正序
                String[] temp = new String[page.ascs().length + 1];
                for (int i = 0; i < page.ascs().length; i++) {
                    temp[i] = page.ascs()[i];
                }
                temp[page.ascs().length] = "orderNum";
                page.setAsc(temp);
            }
        }
        //最终都处理成根据createTime降序
        if (page.descs() == null) {
            page.setDesc("createTime");
        } else {
            if (!ArrayUtils.contains(page.ascs(), "createTime") && !ArrayUtils.contains(page.descs(), "createTime")) {  //createTime既没有设置升序，也没有设置为降序
                // 拼装创建时间倒叙
                String[] temp = new String[page.descs().length + 1];
                for (int i = 0; i < page.descs().length; i++) {
                    temp[i] = page.descs()[i];
                }
                temp[page.descs().length] = "createTime";
                page.setDesc(temp);
            }
        }
        return page;
    }

    private int getIntInRequest(HttpServletRequest request, String paramName, int defaultValue) {
        String s = request.getParameter(paramName);
        if (StringUtils.isBlank(s)) {
            return defaultValue;
        }
        return Integer.parseInt(s);
    }

    private Boolean getBooleanInRequest(HttpServletRequest request, String paramName, Boolean defaultValue) {
        String s = request.getParameter(paramName);
        if (StringUtils.isBlank(s)) {
            return defaultValue;
        }
        return Boolean.getBoolean(s);
    }
}
